package com.syh.jn.scm.service.impl.supplier.statistics;

import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import cn.redscarf.commons.wrapper.expression.orderExpression.Order;
import com.syh.jn.scm.domain.supplier.repository.finance.archive.ArchiveReadRepository;
import com.syh.jn.scm.dto.supplier.finance.archive.ArchiveStockVo;
import com.syh.jn.scm.dto.supplier.finance.archive.ArchiveVo;
import com.syh.jn.scm.dto.supplier.statistics.stock.InventoryReportVo;
import com.syh.jn.scm.infrastructure.repository.utils.MybatisTemplate;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用于获取商品时间范围内的出入库与结存信息的工具类
 */
public class StockInventoryUtils {
  private static ArchiveReadRepository archiveReadRepository;
  static {
    archiveReadRepository = (ArchiveReadRepository) SpringContextUtils.getBean("archiveRepoMbImpl");
  }
  private StockInventoryUtils(){}

  public static Map<String,InventoryReportVo> getStockInventory(String beginTimeStamp,String endTimeStamp, Long businessEntityId) {
    beginTimeStamp = beginTimeStamp == null ? "0" : beginTimeStamp;
    endTimeStamp = beginTimeStamp == null ? String.valueOf(System.currentTimeMillis()) : endTimeStamp;
    Map<String, InventoryReportVo> inventoryReportVoMap = StockInventoryUtils.getBeginStock(beginTimeStamp, businessEntityId);
    StockInventoryUtils.setMiddleStock(beginTimeStamp, endTimeStamp, businessEntityId, inventoryReportVoMap);
    StockInventoryUtils.setEndStock(endTimeStamp,businessEntityId,inventoryReportVoMap);
    return inventoryReportVoMap;
  }
  /**
   * 获取统计报表的期初数据(期初库存)
   * @param beginTimeStamp 开始时间
   * @param businessEntityId 服务商id
   * @return
   */
  private static Map<String,InventoryReportVo> getBeginStock(String beginTimeStamp,Long businessEntityId) {
    Map<String,InventoryReportVo> inventoryReportVoMap = new HashMap<>();
    List<InventoryReportVo> inventoryReportVos = null;
    Map<String,Object> param = new HashMap<>();
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq("businessEntityId",businessEntityId)).append(Restrictions.lt("archiveEndTimeStamp",beginTimeStamp)).order(Order.desc("archiveEndTimeStamp"));
    ArchiveVo archiveVo = archiveReadRepository.getOne(wrapper);
    if (archiveVo != null) {
      List<ArchiveStockVo> archiveStockVos = (List<ArchiveStockVo>) archiveReadRepository.findStockByArchiveId(archiveVo.getId());
      param.put("beginTime",archiveVo.getArchiveEndTimeStamp());
      param.put("endTime",beginTimeStamp);
      param.put("businessEntityId",businessEntityId);
      inventoryReportVos = MybatisTemplate.selectList("stockInventoryQRepository.getStockRecordByTimeFrame",param);
      inventoryReportVos.forEach(inventoryReportVo -> {
        inventoryReportVo.setBeginningQuantity(inventoryReportVo.getRecordQuantity());
        inventoryReportVo.setBeginningBalance(inventoryReportVo.getRecordBalance());
        //平均成本为库存总额除以库存数量
        BigDecimal avgCost = inventoryReportVo.getRecordQuantity().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : inventoryReportVo.getRecordBalance().divide(inventoryReportVo.getRecordQuantity(),5);
        inventoryReportVo.setBeginningAvgCost(avgCost);

        //其余字段清零
        inventoryReportVo.setRecordQuantity(BigDecimal.ZERO);
        inventoryReportVo.setRecordBalance(BigDecimal.ZERO);
        inventoryReportVo.setRecordAvgCost(BigDecimal.ZERO);
        inventoryReportVo.setSaleQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherInQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherInAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherOutQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherOutAmount(BigDecimal.ZERO);
        inventoryReportVo.setLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherSpillAmount(BigDecimal.ZERO);
        inventoryReportVoMap.put(inventoryReportVo.getDepotId()+":"+inventoryReportVo.getGoodsId(),inventoryReportVo);
      });
      archiveStockVos.forEach(archiveStockVo -> {
        String key = archiveStockVo.getDepotId()+":"+archiveStockVo.getGoodsId();
        if (inventoryReportVoMap.get(key) != null) {
          InventoryReportVo inventoryReportVo = inventoryReportVoMap.get(key);
          //库存数量为期初库存加时间段内库存
          BigDecimal quantity = archiveStockVo.getTotalQuantity().add(inventoryReportVo.getBeginningQuantity());
          inventoryReportVo.setBeginningQuantity(quantity);
          //库存总额为期初总额加时间段内总额
          BigDecimal balance = archiveStockVo.getTotalBalance().add(inventoryReportVo.getRecordBalance());
          inventoryReportVo.setBeginningBalance(balance);
          //平均成本为库存总额除以库存数量
          BigDecimal avgCost = quantity.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : balance.divide(quantity,5);
          inventoryReportVo.setBeginningAvgCost(avgCost);
        }
      });
    } else {
      param.put("endTime",beginTimeStamp);
      param.put("businessEntityId",businessEntityId);
      param.put("startRow",0);
      param.put("pageSize",Integer.MAX_VALUE);
      inventoryReportVos = MybatisTemplate.selectList("stockInventoryQRepository.inventoryReport",param);
      inventoryReportVos.forEach(inventoryReportVo -> {
        //期初库存为期初加时间段库存
        inventoryReportVo.setBeginningQuantity(inventoryReportVo.getRecordQuantity().add(inventoryReportVo.getBeginningQuantity()));
        //期初总额为时间段总格
        inventoryReportVo.setBeginningBalance(inventoryReportVo.getRecordBalance().add(inventoryReportVo.getBeginningBalance()));
        BigDecimal avgCost = inventoryReportVo.getBeginningQuantity().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : inventoryReportVo.getRecordBalance().divide(inventoryReportVo.getRecordQuantity(),5);
        inventoryReportVo.setBeginningAvgCost(avgCost);
        //其余字段清零
        inventoryReportVo.setRecordQuantity(BigDecimal.ZERO);
        inventoryReportVo.setRecordBalance(BigDecimal.ZERO);
        inventoryReportVo.setRecordAvgCost(BigDecimal.ZERO);
        inventoryReportVo.setSaleQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherInQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherInAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherOutQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherOutAmount(BigDecimal.ZERO);
        inventoryReportVo.setLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherLossQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherLossAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setSaleRetSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurSpillAmount(BigDecimal.ZERO);
        inventoryReportVo.setPurRetQuantity(BigDecimal.ZERO);
        inventoryReportVo.setPurRetAmount(BigDecimal.ZERO);
        inventoryReportVo.setOtherSpillQuantity(BigDecimal.ZERO);
        inventoryReportVo.setOtherSpillAmount(BigDecimal.ZERO);
        inventoryReportVoMap.put(inventoryReportVo.getDepotId()+":"+inventoryReportVo.getGoodsId(),inventoryReportVo);
      });
    }
    return inventoryReportVoMap;
  }

  /**
   * 获取统计报表的结尾数据(总库存)
   * @param endTimeStamp 结束时间
   * @param businessEntityId 供应商id
   * @param beginInventoryReportVoMap 期初信息
   */
  private static void setEndStock(String endTimeStamp, Long businessEntityId, Map<String,InventoryReportVo> beginInventoryReportVoMap) {
    Map<String, InventoryReportVo> inventoryReportVoMap = new HashMap<>();
    List<InventoryReportVo> inventoryReportVos = null;
    Map<String,Object> param = new HashMap<>();
    Wrapper wrapper = Wrapper.build().append(Restrictions.eq("businessEntityId",businessEntityId)).append(Restrictions.lt("archiveEndTimeStamp",endTimeStamp)).order(Order.desc("archiveEndTimeStamp"));
    ArchiveVo archiveVo = archiveReadRepository.getOne(wrapper);
    if (archiveVo != null) {
      List<ArchiveStockVo> archiveStockVos = (List<ArchiveStockVo>) archiveReadRepository.findStockByArchiveId(archiveVo.getId());
      param.put("beginTime",archiveVo.getArchiveEndTimeStamp());
      param.put("endTime",endTimeStamp);
      param.put("businessEntityId",businessEntityId);
      inventoryReportVos = MybatisTemplate.selectList("stockInventoryQRepository.getStockRecordByTimeFrame",param);
      inventoryReportVos.forEach(inventoryReportVo -> {
        inventoryReportVoMap.put(inventoryReportVo.getDepotId()+":"+inventoryReportVo.getGoodsId(),inventoryReportVo);
      });
      archiveStockVos.forEach(archiveStockVo -> {
        String key = archiveStockVo.getDepotId()+":"+archiveStockVo.getGoodsId();
        if (inventoryReportVoMap.get(key) != null) {
          InventoryReportVo inventoryReportVo = inventoryReportVoMap.get(key);
          //库存数量为结存总数加时间段内库存
          BigDecimal quantity = archiveStockVo.getTotalQuantity().add(inventoryReportVo.getRecordQuantity());
          inventoryReportVo.setBeginningQuantity(quantity);
          inventoryReportVo.setTotalQuantity(quantity);
          //库存总额为结存总额加时间段内总额
          BigDecimal balance = archiveStockVo.getTotalBalance().add(inventoryReportVo.getRecordBalance());
          inventoryReportVo.setBeginningBalance(balance);
          inventoryReportVo.setTotalBalance(balance);
          //平均成本为结存总额除以库存数量
          BigDecimal avgCost = quantity.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : balance.divide(quantity, 5);
          inventoryReportVo.setBeginningAvgCost(avgCost);
          inventoryReportVo.setTotalAvgCost(avgCost);
        }
      });
    } else {
      param.put("endTime",endTimeStamp);
      param.put("businessEntityId",businessEntityId);
      param.put("startRow",0);
      param.put("pageSize",Integer.MAX_VALUE);
      inventoryReportVos = MybatisTemplate.selectList("stockInventoryQRepository.inventoryReport",param);
      inventoryReportVos.forEach(inventoryReportVo -> {
        //期初库存为总库存
        inventoryReportVo.setBeginningQuantity(inventoryReportVo.getTotalQuantity());
        //期初总额为总库存总额
        inventoryReportVo.setBeginningBalance(inventoryReportVo.getTotalBalance());
        //平均成本为总库存平均成本
        inventoryReportVo.setBeginningAvgCost(inventoryReportVo.getTotalAvgCost());
        inventoryReportVoMap.put(inventoryReportVo.getDepotId()+":"+inventoryReportVo.getGoodsId(),inventoryReportVo);
      });
    }

    //拼接
    for (String key: beginInventoryReportVoMap.keySet()) {
      if (inventoryReportVoMap.get(key) != null) {
        InventoryReportVo beginInventoryReportVo = beginInventoryReportVoMap.get(key);
        InventoryReportVo endInventoryReportVo = inventoryReportVoMap.get(key);
        beginInventoryReportVo.setTotalQuantity(endInventoryReportVo.getTotalQuantity());
        beginInventoryReportVo.setTotalBalance(endInventoryReportVo.getTotalBalance());
        beginInventoryReportVo.setTotalAvgCost(endInventoryReportVo.getTotalAvgCost());

        beginInventoryReportVo.setSaleQuantity(beginInventoryReportVo.getSaleQuantity().add(endInventoryReportVo.getSaleQuantity()));
        beginInventoryReportVo.setSaleAmount(beginInventoryReportVo.getSaleAmount().add(endInventoryReportVo.getSaleAmount()));
        beginInventoryReportVo.setSaleRetQuantity(beginInventoryReportVo.getSaleRetQuantity().add(endInventoryReportVo.getSaleRetQuantity()));
        beginInventoryReportVo.setSaleRetAmount(beginInventoryReportVo.getSaleRetAmount().add(endInventoryReportVo.getSaleRetAmount()));
        beginInventoryReportVo.setPurQuantity(beginInventoryReportVo.getPurQuantity().add(endInventoryReportVo.getPurQuantity()));
        beginInventoryReportVo.setPurAmount(beginInventoryReportVo.getPurAmount().add(endInventoryReportVo.getPurAmount()));
        beginInventoryReportVo.setPurRetQuantity(beginInventoryReportVo.getPurRetQuantity().add(endInventoryReportVo.getPurRetQuantity()));
        beginInventoryReportVo.setPurRetAmount(beginInventoryReportVo.getPurRetAmount().add(endInventoryReportVo.getPurRetAmount()));
        beginInventoryReportVo.setOtherInQuantity(beginInventoryReportVo.getOtherInQuantity().add(endInventoryReportVo.getOtherInQuantity()));
        beginInventoryReportVo.setOtherInAmount(beginInventoryReportVo.getOtherInAmount().add(endInventoryReportVo.getOtherInAmount()));
        beginInventoryReportVo.setOtherOutQuantity(beginInventoryReportVo.getOtherOutQuantity().add(endInventoryReportVo.getOtherOutQuantity()));
        beginInventoryReportVo.setOtherOutAmount(beginInventoryReportVo.getOtherOutAmount().add(endInventoryReportVo.getOtherOutAmount()));
        beginInventoryReportVo.setLossQuantity(beginInventoryReportVo.getLossQuantity().add(endInventoryReportVo.getLossQuantity()));
        beginInventoryReportVo.setLossAmount(beginInventoryReportVo.getLossAmount().add(endInventoryReportVo.getLossAmount()));
        beginInventoryReportVo.setSpillQuantity(beginInventoryReportVo.getSpillQuantity().add(endInventoryReportVo.getSpillQuantity()));
        beginInventoryReportVo.setSpillAmount(beginInventoryReportVo.getSpillAmount().add(endInventoryReportVo.getSpillAmount()));
        beginInventoryReportVo.setSaleLossQuantity(beginInventoryReportVo.getSaleLossQuantity().add(endInventoryReportVo.getSaleLossQuantity()));
        beginInventoryReportVo.setSaleLossAmount(beginInventoryReportVo.getSaleLossAmount().add(endInventoryReportVo.getSaleLossAmount()));
        beginInventoryReportVo.setSaleRetLossQuantity(beginInventoryReportVo.getSaleRetLossQuantity().add(endInventoryReportVo.getSaleRetLossQuantity()));
        beginInventoryReportVo.setSaleRetLossAmount(beginInventoryReportVo.getSaleRetLossAmount().add(endInventoryReportVo.getSaleRetLossAmount()));
        beginInventoryReportVo.setPurLossQuantity(beginInventoryReportVo.getPurLossQuantity().add(endInventoryReportVo.getPurLossQuantity()));
        beginInventoryReportVo.setPurLossAmount(beginInventoryReportVo.getPurLossAmount().add(endInventoryReportVo.getPurLossAmount()));
        beginInventoryReportVo.setPurRetLossQuantity(beginInventoryReportVo.getPurRetLossQuantity().add(endInventoryReportVo.getPurRetLossQuantity()));
        beginInventoryReportVo.setPurRetLossAmount(beginInventoryReportVo.getPurRetLossAmount().add(endInventoryReportVo.getPurRetLossAmount()));
        beginInventoryReportVo.setOtherLossQuantity(beginInventoryReportVo.getOtherLossQuantity().add(endInventoryReportVo.getOtherLossQuantity()));
        beginInventoryReportVo.setOtherLossAmount(beginInventoryReportVo.getOtherLossAmount().add(endInventoryReportVo.getOtherLossAmount()));
        beginInventoryReportVo.setSaleSpillQuantity(beginInventoryReportVo.getSaleSpillQuantity().add(endInventoryReportVo.getSaleSpillQuantity()));
        beginInventoryReportVo.setSaleSpillAmount(beginInventoryReportVo.getSaleSpillAmount().add(endInventoryReportVo.getSaleSpillAmount()));
        beginInventoryReportVo.setSaleRetSpillQuantity(beginInventoryReportVo.getSaleRetSpillQuantity().add(endInventoryReportVo.getSaleRetSpillQuantity()));
        beginInventoryReportVo.setSaleRetSpillAmount(beginInventoryReportVo.getSaleRetSpillAmount().add(endInventoryReportVo.getSaleRetSpillAmount()));
        beginInventoryReportVo.setPurSpillQuantity(beginInventoryReportVo.getPurSpillQuantity().add(endInventoryReportVo.getPurSpillQuantity()));
        beginInventoryReportVo.setPurSpillAmount(beginInventoryReportVo.getPurSpillAmount().add(endInventoryReportVo.getPurSpillAmount()));
        beginInventoryReportVo.setPurRetSpillQuantity(beginInventoryReportVo.getPurRetSpillQuantity().add(endInventoryReportVo.getPurRetSpillQuantity()));
        beginInventoryReportVo.setPurRetSpillAmount(beginInventoryReportVo.getPurRetSpillAmount().add(endInventoryReportVo.getPurRetSpillAmount()));
        beginInventoryReportVo.setOtherSpillQuantity(beginInventoryReportVo.getOtherSpillQuantity().add(endInventoryReportVo.getOtherSpillQuantity()));
        beginInventoryReportVo.setOtherSpillAmount(beginInventoryReportVo.getOtherSpillAmount().add(endInventoryReportVo.getOtherSpillAmount()));
        beginInventoryReportVo.setRecordQuantity(beginInventoryReportVo.getRecordQuantity().add(endInventoryReportVo.getRecordQuantity()));
        beginInventoryReportVo.setRecordBalance(beginInventoryReportVo.getRecordBalance().add(endInventoryReportVo.getRecordBalance()));
        BigDecimal avgCost = beginInventoryReportVo.getRecordQuantity().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : beginInventoryReportVo.getRecordBalance().divide(beginInventoryReportVo.getRecordQuantity(), 5);
        beginInventoryReportVo.setRecordAvgCost(avgCost);
      }
    }
  }

  /**
   * 获取统计中间的出入库数据
   * @param beginTimeStamp 开始时间
   * @param endTimeStamp 结束时间
   * @param businessEntityId 服务商id
   * @param beginInventoryReportVoMap 期初信息
   * @return
   */
  private static void setMiddleStock(String beginTimeStamp,String endTimeStamp,Long businessEntityId,Map<String,InventoryReportVo> beginInventoryReportVoMap) {
    Map<String,Object> param = new HashMap<>();
    Wrapper wrapper = Wrapper.build().append(Restrictions.gt("archiveEndTimeStamp",beginTimeStamp))
            .append(Restrictions.lt("archiveEndTimeStamp",endTimeStamp))
            .append(Restrictions.eq("businessEntityId",businessEntityId))
            .order(Order.asc("archiveEndTimeStamp"));
    List<ArchiveVo> archiveVos = archiveReadRepository.getList(wrapper);
    if (!archiveVos.isEmpty()) {
      param.put("beginTime",beginTimeStamp);
      param.put("endTime",archiveVos.get(0).getArchiveEndTimeStamp());
      param.put("businessEntityId",businessEntityId);
      param.put("startRow",0);
      param.put("pageSize",Integer.MAX_VALUE);
      List<InventoryReportVo> inventoryReportVos = MybatisTemplate.selectList("stockInventoryQRepository.inventoryReport",param);
      inventoryReportVos.forEach(inventoryReportVo -> {
        String key = inventoryReportVo.getDepotId()+":"+inventoryReportVo.getGoodsId();
        if (beginInventoryReportVoMap.get(key) != null) {
          InventoryReportVo beginInventoryReportVo = beginInventoryReportVoMap.get(key);
          beginInventoryReportVo.setSaleQuantity(beginInventoryReportVo.getSaleQuantity().add(inventoryReportVo.getSaleQuantity()));
          beginInventoryReportVo.setSaleAmount(beginInventoryReportVo.getSaleAmount().add(inventoryReportVo.getSaleAmount()));
          beginInventoryReportVo.setSaleRetQuantity(beginInventoryReportVo.getSaleRetQuantity().add(inventoryReportVo.getSaleRetQuantity()));
          beginInventoryReportVo.setSaleRetAmount(beginInventoryReportVo.getSaleRetAmount().add(inventoryReportVo.getSaleRetAmount()));
          beginInventoryReportVo.setPurQuantity(beginInventoryReportVo.getPurQuantity().add(inventoryReportVo.getPurQuantity()));
          beginInventoryReportVo.setPurAmount(beginInventoryReportVo.getPurAmount().add(inventoryReportVo.getPurAmount()));
          beginInventoryReportVo.setPurRetQuantity(beginInventoryReportVo.getPurRetQuantity().add(inventoryReportVo.getPurRetQuantity()));
          beginInventoryReportVo.setPurRetAmount(beginInventoryReportVo.getPurRetAmount().add(inventoryReportVo.getPurRetAmount()));
          beginInventoryReportVo.setOtherInQuantity(beginInventoryReportVo.getOtherInQuantity().add(inventoryReportVo.getOtherInQuantity()));
          beginInventoryReportVo.setOtherInAmount(beginInventoryReportVo.getOtherInAmount().add(inventoryReportVo.getOtherInAmount()));
          beginInventoryReportVo.setOtherOutQuantity(beginInventoryReportVo.getOtherOutQuantity().add(inventoryReportVo.getOtherOutQuantity()));
          beginInventoryReportVo.setOtherOutAmount(beginInventoryReportVo.getOtherOutAmount().add(inventoryReportVo.getOtherOutAmount()));
          beginInventoryReportVo.setLossQuantity(beginInventoryReportVo.getLossQuantity().add(inventoryReportVo.getLossQuantity()));
          beginInventoryReportVo.setLossAmount(beginInventoryReportVo.getLossAmount().add(inventoryReportVo.getLossAmount()));
          beginInventoryReportVo.setSpillQuantity(beginInventoryReportVo.getSpillQuantity().add(inventoryReportVo.getSpillQuantity()));
          beginInventoryReportVo.setSpillAmount(beginInventoryReportVo.getSpillAmount().add(inventoryReportVo.getSpillAmount()));
          beginInventoryReportVo.setSaleLossQuantity(beginInventoryReportVo.getSaleLossQuantity().add(inventoryReportVo.getSaleLossQuantity()));
          beginInventoryReportVo.setSaleLossAmount(beginInventoryReportVo.getSaleLossAmount().add(inventoryReportVo.getSaleLossAmount()));
          beginInventoryReportVo.setSaleRetLossQuantity(beginInventoryReportVo.getSaleRetLossQuantity().add(inventoryReportVo.getSaleRetLossQuantity()));
          beginInventoryReportVo.setSaleRetLossAmount(beginInventoryReportVo.getSaleRetLossAmount().add(inventoryReportVo.getSaleRetLossAmount()));
          beginInventoryReportVo.setPurLossQuantity(beginInventoryReportVo.getPurLossQuantity().add(inventoryReportVo.getPurLossQuantity()));
          beginInventoryReportVo.setPurLossAmount(beginInventoryReportVo.getPurLossAmount().add(inventoryReportVo.getPurLossAmount()));
          beginInventoryReportVo.setPurRetLossQuantity(beginInventoryReportVo.getPurRetLossQuantity().add(inventoryReportVo.getPurRetLossQuantity()));
          beginInventoryReportVo.setPurRetLossAmount(beginInventoryReportVo.getPurRetLossAmount().add(inventoryReportVo.getPurRetLossAmount()));
          beginInventoryReportVo.setOtherLossQuantity(beginInventoryReportVo.getOtherLossQuantity().add(inventoryReportVo.getOtherLossQuantity()));
          beginInventoryReportVo.setOtherLossAmount(beginInventoryReportVo.getOtherLossAmount().add(inventoryReportVo.getOtherLossAmount()));
          beginInventoryReportVo.setSaleSpillQuantity(beginInventoryReportVo.getSaleSpillQuantity().add(inventoryReportVo.getSaleSpillQuantity()));
          beginInventoryReportVo.setSaleSpillAmount(beginInventoryReportVo.getSaleSpillAmount().add(inventoryReportVo.getSaleSpillAmount()));
          beginInventoryReportVo.setSaleRetSpillQuantity(beginInventoryReportVo.getSaleRetSpillQuantity().add(inventoryReportVo.getSaleRetSpillQuantity()));
          beginInventoryReportVo.setSaleRetSpillAmount(beginInventoryReportVo.getSaleRetSpillAmount().add(inventoryReportVo.getSaleRetSpillAmount()));
          beginInventoryReportVo.setPurSpillQuantity(beginInventoryReportVo.getPurSpillQuantity().add(inventoryReportVo.getPurSpillQuantity()));
          beginInventoryReportVo.setPurSpillAmount(beginInventoryReportVo.getPurSpillAmount().add(inventoryReportVo.getPurSpillAmount()));
          beginInventoryReportVo.setPurRetSpillQuantity(beginInventoryReportVo.getPurRetSpillQuantity().add(inventoryReportVo.getPurRetSpillQuantity()));
          beginInventoryReportVo.setPurRetSpillAmount(beginInventoryReportVo.getPurRetSpillAmount().add(inventoryReportVo.getPurRetSpillAmount()));
          beginInventoryReportVo.setOtherSpillQuantity(beginInventoryReportVo.getOtherSpillQuantity().add(inventoryReportVo.getOtherSpillQuantity()));
          beginInventoryReportVo.setOtherSpillAmount(beginInventoryReportVo.getOtherSpillAmount().add(inventoryReportVo.getOtherSpillAmount()));
          beginInventoryReportVo.setRecordQuantity(beginInventoryReportVo.getRecordQuantity().add(inventoryReportVo.getRecordQuantity()));
          beginInventoryReportVo.setRecordBalance(beginInventoryReportVo.getRecordBalance().add(inventoryReportVo.getRecordBalance()));
          BigDecimal avgCost = beginInventoryReportVo.getRecordQuantity().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : beginInventoryReportVo.getRecordBalance().divide(beginInventoryReportVo.getRecordQuantity(),5);
          beginInventoryReportVo.setRecordAvgCost(avgCost);
        }
      });
    }
    if (archiveVos.size() > 1) {
      Wrapper betweenWp = Wrapper.build().append(Restrictions.gt("archiveEndTimeStamp",archiveVos.get(0).getArchiveEndTimeStamp()))
              .append(Restrictions.lt("archiveEndTimeStamp",endTimeStamp))
              .append(Restrictions.eq("businessEntityId",businessEntityId))
              .order(Order.asc("archiveEndTimeStamp"));
      List<ArchiveStockVo> archiveStockVos = (List<ArchiveStockVo>) archiveReadRepository.findStock(betweenWp);
      archiveStockVos.forEach(archiveStockVo -> {
        String key = archiveStockVo.getDepotId()+":"+archiveStockVo.getGoodsId();
        if (beginInventoryReportVoMap.get(key) != null) {
          InventoryReportVo inventoryReportVo = beginInventoryReportVoMap.get(key);
          inventoryReportVo.setSaleQuantity(inventoryReportVo.getSaleQuantity().add(archiveStockVo.getSaleQuantity()));
          inventoryReportVo.setSaleAmount(inventoryReportVo.getSaleAmount().add(archiveStockVo.getSaleAmount()));
          inventoryReportVo.setSaleRetQuantity(inventoryReportVo.getSaleRetQuantity().add(archiveStockVo.getSaleReturnQuantity()));
          inventoryReportVo.setSaleRetAmount(inventoryReportVo.getSaleRetAmount().add(archiveStockVo.getSaleReturnAmount()));
          inventoryReportVo.setPurQuantity(inventoryReportVo.getPurQuantity().add(archiveStockVo.getPurchaseQuantity()));
          inventoryReportVo.setPurAmount(inventoryReportVo.getPurAmount().add(archiveStockVo.getPurchaseAmount()));
          inventoryReportVo.setPurRetQuantity(inventoryReportVo.getPurRetQuantity().add(archiveStockVo.getPurchaseReturnQuantity()));
          inventoryReportVo.setPurRetAmount(inventoryReportVo.getPurRetAmount().add(archiveStockVo.getPurchaseReturnAmount()));
          inventoryReportVo.setOtherInQuantity(inventoryReportVo.getOtherInQuantity().add(archiveStockVo.getOtherInQuantity()));
          inventoryReportVo.setOtherInAmount(inventoryReportVo.getOtherInAmount().add(archiveStockVo.getOtherInAmount()));
          inventoryReportVo.setOtherOutQuantity(inventoryReportVo.getOtherOutQuantity().add(archiveStockVo.getOtherOutQuantity()));
          inventoryReportVo.setOtherOutAmount(inventoryReportVo.getOtherOutAmount().add(archiveStockVo.getOtherOutAmount()));
          inventoryReportVo.setLossQuantity(inventoryReportVo.getLossQuantity().add(archiveStockVo.getLossQuantity()));
          inventoryReportVo.setLossAmount(inventoryReportVo.getLossAmount().add(archiveStockVo.getLossAmount()));
          inventoryReportVo.setSpillQuantity(inventoryReportVo.getSpillQuantity().add(archiveStockVo.getSpillQuantity()));
          inventoryReportVo.setSpillAmount(inventoryReportVo.getSpillAmount().add(archiveStockVo.getSpillAmount()));
          inventoryReportVo.setSaleLossQuantity(inventoryReportVo.getSaleLossQuantity().add(archiveStockVo.getSaleLossQuantity()));
          inventoryReportVo.setSaleLossAmount(inventoryReportVo.getSaleLossAmount().add(archiveStockVo.getSaleLossAmount()));
          inventoryReportVo.setSaleRetLossQuantity(inventoryReportVo.getSaleRetLossQuantity().add(archiveStockVo.getSaleReturnLossQuantity()));
          inventoryReportVo.setSaleRetLossAmount(inventoryReportVo.getSaleRetLossAmount().add(archiveStockVo.getSaleReturnLossAmount()));
          inventoryReportVo.setPurLossQuantity(inventoryReportVo.getPurLossQuantity().add(archiveStockVo.getPurchaseLossQuantity()));
          inventoryReportVo.setPurLossAmount(inventoryReportVo.getPurLossAmount().add(archiveStockVo.getPurchaseLossAmount()));
          inventoryReportVo.setPurRetLossQuantity(inventoryReportVo.getPurRetLossQuantity().add(archiveStockVo.getPurchaseReturnLossQuantity()));
          inventoryReportVo.setPurRetLossAmount(inventoryReportVo.getPurRetLossAmount().add(archiveStockVo.getPurchaseReturnLossAmount()));
          inventoryReportVo.setOtherLossQuantity(inventoryReportVo.getOtherLossQuantity().add(archiveStockVo.getOtherLossQuantity()));
          inventoryReportVo.setOtherLossAmount(inventoryReportVo.getOtherLossAmount().add(archiveStockVo.getOtherLossAmount()));
          inventoryReportVo.setSaleSpillQuantity(inventoryReportVo.getSaleSpillQuantity().add(archiveStockVo.getSaleSpillQuantity()));
          inventoryReportVo.setSaleSpillAmount(inventoryReportVo.getSaleSpillAmount().add(archiveStockVo.getSaleSpillAmount()));
          inventoryReportVo.setSaleRetSpillQuantity(inventoryReportVo.getSaleRetSpillQuantity().add(archiveStockVo.getSaleReturnSpillQuantity()));
          inventoryReportVo.setSaleRetSpillAmount(inventoryReportVo.getSaleRetSpillAmount().add(archiveStockVo.getSaleReturnSpillAmount()));
          inventoryReportVo.setPurSpillQuantity(inventoryReportVo.getPurSpillQuantity().add(archiveStockVo.getPurchaseSpillQuantity()));
          inventoryReportVo.setPurSpillAmount(inventoryReportVo.getPurSpillAmount().add(archiveStockVo.getPurchaseSpillAmount()));
          inventoryReportVo.setPurRetSpillQuantity(inventoryReportVo.getPurRetSpillQuantity().add(archiveStockVo.getPurchaseReturnSpillQuantity()));
          inventoryReportVo.setPurRetSpillAmount(inventoryReportVo.getPurRetSpillAmount().add(archiveStockVo.getPurchaseReturnSpillAmount()));
          inventoryReportVo.setOtherSpillQuantity(inventoryReportVo.getOtherSpillQuantity().add(archiveStockVo.getOtherSpillQuantity()));
          inventoryReportVo.setOtherSpillAmount(inventoryReportVo.getOtherSpillAmount().add(archiveStockVo.getOtherSpillAmount()));
          inventoryReportVo.setRecordQuantity(inventoryReportVo.getRecordQuantity().add(archiveStockVo.getRecordQuantity()));
          inventoryReportVo.setRecordBalance(inventoryReportVo.getRecordBalance().add(archiveStockVo.getRecordBalance()));
          BigDecimal avgCost = inventoryReportVo.getRecordQuantity().compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : inventoryReportVo.getRecordBalance().divide(inventoryReportVo.getRecordQuantity(),BigDecimal.ROUND_HALF_UP);
          inventoryReportVo.setRecordAvgCost(avgCost);
        }
      });
    }
  }

}
